use16       ; We need 16-bit intructions for Real mode

ORG 0x7C00    ; The BIOS loads the boot sector into memory location 0x7C00

reset_drive:
	mov ah, 0               ; RESET-command
	int 13h                 ; Call interrupt 13h
	or ah, ah               ; Check for error code
	jnz reset_drive         ; Try again if ah != 0
	
	mov ax, 0
	mov es, ax
	mov bx, 0x1000          ; Destination address = 0000:1000
	
	mov ah, 02h             ; READ SECTOR-command
	mov al, 11h             ; Number of sectors to read
	mov ch, 0               ; Cylinder = 0
	mov cl, 02h             ; Sector = 2
	mov dh, 0               ; Head = 0
	int 13h                 ; Call interrupt 13h
	or ah, ah               ; Check for error code
	jnz reset_drive         ; Try again if ah != 0
	
	cli                     ; Disable interrupts, we want to be alone
	
	xor ax, ax
	mov ds, ax              ; Set DS-register to 0 - used by lgdt
	
	lgdt [gdt_desc]         ; Load the GDT descriptor
	
	mov eax, cr0            ; Copy the contents of CR0 into EAX
	or eax, 1               ; Set bit 0
	mov cr0, eax            ; Copy the contents of EAX into CR0
	
	jmp 08h:clear_pipe      ; Jump to code segment, offset clear_pipe

use32                       ; We now need 32-bit instructions
clear_pipe:
	mov ax, 10h             ; Save data segment identifyer
	mov ds, ax              ; Move a valid data segment into the data segment register
	mov ss, ax              ; Move a valid data segment into the stack segment register
	mov esp, 090000h        ; Move the stack pointer to 090000h
	
	jmp 08h:01000h          ; Jump to section 08h (code), offset 01000h

gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
	dd 0
	dd 0

gdt_code:               ; Code segment, read/execute, nonconforming
	dw 0FFFFh
	dw 0
	db 0
	db 10011010b
	db 11001111b
	db 0

gdt_data:               ; Data segment, read/write, expand down
	dw 0FFFFh
	dw 0
	db 0
	db 10010010b
	db 11001111b
	db 0

gdt_end:                ; Used to calculate the size of the GDT

gdt_desc:                       ; The GDT descriptor
	dw gdt_end - gdt - 1    ; Limit (size)
	dd gdt                  ; Address of the GDT

times 510-($-$$) db 0           ; Fill up the file with zeros
	dw 0AA55h                ; Boot sector identifyer
